package thread.communication;

/**
 * @author 真香
 * @create 2021-06-04 21:00
 */

import com.sun.org.apache.xalan.internal.xsltc.cmdline.Compile;

/**
 * 测试：生产者消费者——》利用缓冲区解决:管程法
 * 生产者 消费者 产品 缓冲区
 *
 */
public class TestPC {


    public static void main(String[] args){
        Buffer buffer = new Buffer();
        new Productor(buffer).start();
        new Comsumer(buffer).start();

    }
}


// 生产者
class  Productor extends Thread {
    Buffer container;

    public Productor(Buffer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            container.push(new Product(i));
            System.out.println("生产了第"+i+"只鸡");
        }
    }
}

// 消费者

class Comsumer extends Thread {
    Buffer container;

    public Comsumer(Buffer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消费了----"+container.pop().id+"");
        }
    }
}

// 产品
class Product {

    // 产品编号
    public   int id;

    public Product(int id) {
        this.id = id;
    }


}

// 缓冲区
class Buffer{



    // 需要一个指定大小的容器
    Product[] products = new Product[10];


    // 容器计数器
    int count = 0;

    // 生产者放入产品
    public synchronized void push (Product product) {

        // 如果容器满了就等待消费者消费
        if (products.length == count) {
            // 通知消费者消费，生产停滞
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 如果没满就需要丢入产品
        products[count] = product;
        count++;

        //通知消费者消费
        this.notifyAll();
    }

    // 消费者消费产品
    public synchronized Product pop (){
        // 判断能否消费
        if (count ==0) {
            // 等待生产者生产
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 如果可以消费
        count --;
        Product product = products[count];
        // 消费完成，通知生产者生产
        this.notifyAll();
        return product;
    }
}


//

